package aex.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import aex.util.CU;
import aex.util.PageBean;

/**
 * 通用的数据访问层dao。提供单个对象查询，分页查询，更新，删除操作
 * 
 * @author JiangYouYao
 * 
 * @param <T>
 */
public class CommonDao<T> extends HibernateDaoSupport {

	public static final String SERVICE_NAME = "aex.dao.CommonDao";

	@Resource(name = "sessionFactory")
	public final void setSessionFactoryDi(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);

	}

	/**
	 * 子类中泛型的实际类型
	 */
	@SuppressWarnings("rawtypes")
	private Class entiry = CU.getClass(this.getClass());

	/**
	 * @Description: 保存一个对象
	 * @Parameters: T entity 被保存的对象
	 * @Return: void
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */
	public void save(T entity) {
		this.getHibernateTemplate().save(entity);
	}

	/**
	 * @Description: 更新一个对象
	 * @Parameters: T entity 被更新的对象
	 * @Return: void
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public void update(T entity) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().update(entity);
	}

	public void merge(T entity) {
		// TODO Auto-generated method stub
		this.getHibernateTemplate().merge(entity);
	}

	/**
	 * @Description: 通过id寻找一个对象
	 * @Parameters: Serializable id
	 * @Return: 返回DAO的操作泛型类
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public T findObjectByID(Serializable id) {
		@SuppressWarnings("unchecked")
		T temp = (T) this.getHibernateTemplate().get(entiry, id);
		return temp;
	}

	/**
	 * @Description: 通过id数组删除一组对象
	 * @Parameters: Serializable ids
	 * @Return: 无
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public void deleteObjectByIDs(Serializable... ids) {
		for (int i = 0; ids != null && i < ids.length; i++) {
			Serializable id = ids[i];
			Object obj = this.getHibernateTemplate().get(entiry, id);
			if (obj != null) {
				this.getHibernateTemplate().delete(obj);
			}
		}
	}

	/**
	 * @Description: 通过集合删除一组对象
	 * @Parameters: Collection<T> list
	 * @Return: 无
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public void deleteObjectByCollection(Collection<T> list) {
		this.getHibernateTemplate().deleteAll(list);
	}

	/**
	 * @Description: 底层的按条件查询方法。 自动拼装sql语句。<br>
	 *               通过泛型获取查询的表名， 没有分页。默认表的别名为 tName。<br>
	 * @Parameters: String hqlWhere 查询条件<br>
	 *              语句模型： and tName.textName like ?<br>
	 *              final Object[] params, 条件参数<br>
	 *              语句模型： %刘 % <br>
	 *              LinkedHashMap<String, String> orderby 排序方式<br>
	 *              语句模型：orderby.put("tName.textDate", "desc");<br>
	 * @Return: 无
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public List<T> findCollectionByConditionNoPage(String hqlWhere,
			final Object[] params, LinkedHashMap<String, String> orderby) {

		String hql = "from " + entiry.getSimpleName() + " tName where 1=1 ";
		// 组织排序条件
		String hqlOrderBy = " ";
		if (orderby != null) {
			hqlOrderBy = " order by ";
			for (Map.Entry<String, String> map : orderby.entrySet()) {
				// map.getKey(); o.textDate
				// map.getValue(); desc
				hqlOrderBy += map.getKey() + " " + map.getValue() + " ,";
			}
		}
		if(hqlWhere==null){
			hql += hqlOrderBy;
		}else{
			hql += hqlWhere + hqlOrderBy;
		}
		final String finalHal = hql.substring(0, hql.length() - 1);

		@SuppressWarnings("unchecked")
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(finalHal);

						for (int i = 0; params != null && i < params.length; i++) {
							query.setParameter(i, params[i]);
						}
						return query.list();
					}
				});
		return list;
	}

	/**
	 * @Description: 底层的按条件查询方法。 自动拼装sql语句。<br>
	 *               通过泛型获取查询的表名，带分页。默认表的别名为 tName。<br>
	 * @Parameters: String hqlWhere 查询条件<br>
	 *              语句模型： and tName.textName like ?<br>
	 *              final Object[] params, 条件参数<br>
	 *              LinkedHashMap<String, String> orderby 排序方式<br>
	 *              语句模型：orderby.put("tName.textDate", "desc");<br>
	 * @Return: 无
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */
	public List<T> findCollectionByPage(String hqlWhere, final Object[] params,
			LinkedHashMap<String, String> orderby, final int pageNow,
			final int pageSize) {
		String hql = "from " + entiry.getSimpleName() + " tName where 1=1 ";
		// 组织排序条件

		String hqlOrderBy = "  ";
		if (orderby != null) {
			hqlOrderBy = " order by ";
			for (Map.Entry<String, String> map : orderby.entrySet()) {
				// map.getKey(); o.textDate
				// map.getValue(); desc
				// tName.date desc
				hqlOrderBy += map.getKey() + " " + map.getValue() + " ,";
			}
		}

		if(hqlWhere==null){
			hql += hqlOrderBy;
		}else{
			hql += hqlWhere + hqlOrderBy;
		}
		final String finalHal = hql.substring(0, hql.length() - 1);
		CU.deBugPrintln(("finalHal  " + finalHal));
		@SuppressWarnings("unchecked")
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(finalHal);
						for (int i = 0; params != null && i < params.length; i++) {
							query.setParameter(i, params[i]);
						}
						query.setFirstResult((pageNow - 1) * pageSize);
						query.setMaxResults(pageSize);
						return query.list();
					}
				});
		return list;
	}

	public PageBean<T> findPageBean(String hqlWhere, final Object[] params,
			LinkedHashMap<String, String> orderby, final PageBean<T> pageBean) {
		String hql = "from " + entiry.getSimpleName() + " tName where 1=1 ";
		// 组织排序条件
		String hqlOrderBy = " order by ";
		if (orderby != null) {
			for (Map.Entry<String, String> map : orderby.entrySet()) {
				// map.getKey(); o.textDate
				// map.getValue(); desc
				// tName.date desc
				hqlOrderBy += map.getKey() + " " + map.getValue() + " ,";
			}
		}
		
		if(hqlWhere==null){
			hql += hqlOrderBy;
		}else{
			hql += hqlWhere + hqlOrderBy;
		}
		
		final String finalHal = hql.substring(0, hql.length() - 1);
		System.out.println("finalHal  " + finalHal);
		@SuppressWarnings("unchecked")
		List<T> list = (List<T>) this.getHibernateTemplate().execute(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(finalHal);
						for (int i = 0; params != null && i < params.length; i++) {
							query.setParameter(i, params[i]);
						}
						pageBean.setItemCount(query.list().size());
						query.setFirstResult((pageBean.getPageNow() - 1)
								* pageBean.getPageSize());
						query.setMaxResults(pageBean.getPageSize());
						return query.list();
					}
				});
		pageBean.setPageCount((pageBean.getItemCount() - 1)
				/ pageBean.getPageSize() + 1);
		pageBean.setObjList(list);
		return pageBean;
	}



	/**
	 * @Description:带条件查询本dao中统共有多少条数据
	 * @Parameters:hqlWhere 查询的条件 格式 类似于 and id>5
	 * @Return: int 行数
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public int getPageCountWithRestrain(String hqlWhere) {
		String hql = " select count(*) from " + entiry.getSimpleName()
				+ " tName where 1=1 " + hqlWhere;
		return Integer.parseInt(this.getHibernateTemplate().find(hql).get(0)
				.toString());
	}

	/**
	 * @Description: 查询对应表中统共有多少条数据 不带条件
	 * @Parameters:无
	 * @Return: int 行数
	 * @Author: JiangYouYao
	 * @Version: V1.00
	 * @Create Date: 2014-8-12
	 */

	public int getRowCount() {
		String hql = "select count(*) from " + entiry.getSimpleName();
		return Integer.parseInt(this.getHibernateTemplate().find(hql).get(0)
				.toString());
	}

	/**
	 * 通过一个不完整的bean对象查询出一组符合条件的对象，这个比上面写的按条件查询来的更快，更有效
	 */

	@SuppressWarnings("unchecked")
	public List<T> findListByBean(T entiry) {
		// TODO Auto-generated method stub
		return this.getHibernateTemplate().findByExample(entiry);
	}

	/**
	 * 查询一个实例对象如没有则返回空
	 */
	public T findEntiry(T entiry) {

		@SuppressWarnings("unchecked")
		List<T> list = this.getHibernateTemplate().findByExample(entiry);
		if (list.size() > 0) {
			return list.get(0);
		} else {
			return null;
		}
	}

	public void clear() {
		this.getHibernateTemplate().clear();
	}

	/**
	 * 根据查询条件返回有多少条记录
	 * 
	 * @创建人：LK
	 * @param hqlWhere
	 * @param params
	 * @创建时间：2014年12月8日
	 */

	public Integer getPageCountByPage(String hqlWhere, Object[] params) {
		// TODO Auto-generated method stub
		String hql = "select count(*) from " + entiry.getSimpleName()
				+ " tName where 1=1 ";
		hql += hqlWhere;
		@SuppressWarnings("unchecked")
		List<Integer> list = this.getHibernateTemplate().find(hql, params);
		if (list.size() > 0)
			return list.get(0);
		return 0;
	}
	
	/**
	 * 把对象从持久态打回托管状态
	 * @param obj
	 */
	public void evict(Object obj){
		CU.deBugPrintln("清除对象！");
		this.getSession().evict(obj);
	}

	/**
	 * 执行编写好的hql语句
	 * @param hql
	 */
	public  void execHql(final String  hql) {
		this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query  query=session.createQuery(hql);
						return  query.executeUpdate();
					}
				});
}
}
